package top.mcwebsite.playandroid.business.message.impl.vm

import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.paging.cachedIn
import top.mcwebsite.playandroid.business.message.impl.api.MessageApiService
import top.mcwebsite.playandroid.business.message.impl.model.MessageModel
import top.mcwebsite.playandroid.common.network.api.NetworkService
import top.mcwebsite.playandroid.common.network.api.createApi
import top.mcwebsite.playandroid.common.network.model.ApiResult
import top.mcwebsite.playandroid.lib.mvi.base.BaseViewModel
import top.mcwebsite.playandroid.lib.servicemanager.core.ServiceManager

class MessageViewModel : BaseViewModel<MessageIntent, MessageUiState, MessageUiEffect>(
    defaultState = MessageUiState()
) {

    private val apiService: MessageApiService = ServiceManager.getService<NetworkService>().createApi()

    private val unReadMessagePager = Pager(PagingConfig(pageSize = 10)) {
        MessagePagingSource(MessageTab.New)
    }

    val unReadMessagePagerFlow = unReadMessagePager.flow.cachedIn(viewModelScope)

    private val readMessagePager = Pager(PagingConfig(pageSize = 10)) {
        MessagePagingSource(MessageTab.History)
    }

    val readMessagePagerFlow = readMessagePager.flow.cachedIn(viewModelScope)


    override fun handleIntent(intent: MessageIntent) {
        when (intent) {
            is MessageIntent.MessageTabChangeIntent -> {
                setUiState { copy(messageTab = intent.messageTab) }
            }
            is MessageIntent.OnMessageItemClickIntent -> {
                sendUiEffect(MessageUiEffect.GoArticleDetailPageUiEffect(intent.messageModel))
            }
        }
    }

    private inner class MessagePagingSource(
        private val messageTab: MessageTab
    ) : PagingSource<Int, MessageModel>() {
        override fun getRefreshKey(state: PagingState<Int, MessageModel>): Int? {
            return null
        }

        suspend fun loadMessages(page: Int) =
            when (messageTab) {
                MessageTab.New -> apiService.unReadMessages(page)
                MessageTab.History -> apiService.readMessages(page)
            }

        override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MessageModel> {
            return try {
                val nextPageNumber = params.key ?: 1
                when (val result = loadMessages(nextPageNumber)) {
                    is ApiResult.Success -> {
                        LoadResult.Page(
                            data = result.data.data?.datas ?: emptyList(),
                            prevKey = if (nextPageNumber == 1) null else nextPageNumber - 1,
                            nextKey = if (result.data.data?.over == true) null else nextPageNumber + 1
                        )
                    }

                    is ApiResult.Failure -> {
                        LoadResult.Error(result.cause)
                    }
                }
            } catch (e: Exception) {
                return LoadResult.Error(e)
            }
        }

    }

}

enum class MessageTab {
    New, History
}